package com.smartboot.plus.service;

import com.alibaba.fastjson2.JSON;
import com.smartboot.plus.api.ResultCode;
import com.smartboot.plus.condition.ConditionGroup;
import com.smartboot.plus.condition.ConditionQ;
import com.smartboot.plus.exception.ServiceException;
import com.smartboot.plus.ignite.IgniteCacheRegion;
import com.smartboot.plus.ignite.IgniteQueryExecutor;
import com.smartboot.plus.ignite.cache.MqttMetricCache;
import com.smartboot.plus.utils.Func;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import tech.smartboot.feat.cloud.annotation.Autowired;
import tech.smartboot.feat.cloud.annotation.Bean;
import tech.smartboot.feat.cloud.annotation.PostConstruct;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * MQTT 节点指标服务类，用于管理 Ignite 缓存中的节点监控数据。
 * 提供了对节点信息、JVM 指标、端点状态等的查询功能。
 */
@Bean
public class MqttMetricService implements IgniteQueryExecutor<MqttMetricCache> {

    @Autowired
    private Ignite igniteInstance;



    /**
     * 获取当前缓存区域中存储 MQTT 节点指标的 Ignite 缓存实例。
     *
     * @return 返回指定名称的 Ignite 缓存实例。
     */
    @Override
    public IgniteCache<String, MqttMetricCache> getIgniteCache() {
        return igniteInstance.cache(IgniteCacheRegion.MQTT_METRIC_CACHE.getCacheName());
    }
    /**
     * 根据节点ID获取节点信息。
     *
     * @param nodeId 节点ID
     * @return MqttNodeCache对象
     * @throws ServiceException 如果参数缺失或发生异常
     */
    public MqttMetricCache nodeInfoNode(String nodeId) throws ServiceException {

        if (Func.isEmpty(nodeId)) {
            throw new ServiceException(ResultCode.PARAM_MISS.getMessage());
        }
        ConditionGroup conditionGroup = new ConditionGroup().add(ConditionQ.eq(MqttMetricCache::getNodeId, nodeId));
        return this.selectOne(conditionGroup, MqttMetricCache.class);

    }
    /**
     * 初始化方法，用于在 Bean 构造完成后执行一些初始化操作。
     * 当前暂未实现具体逻辑。
     */
    @PostConstruct
    public void init() {
        // 可在此处加载初始数据或建立连接
    }

    /**
     * 查询所有节点的 nodeId 列表，用于下拉框展示。
     *
     * @return 包含所有节点ID的Map列表
     * @throws ServiceException 如果查询失败则抛出异常
     */
    public List<Map<String, String>> clusterDown() {

        List<Map<String, String>> nodeList = new ArrayList<>();
        List<MqttMetricCache> metricList = this.selectList(new ConditionGroup(), MqttMetricCache.class);

        for (MqttMetricCache metric : metricList) {
            Map<String, String> nodeMap = new HashMap<>();
            nodeMap.put("nodeId", metric.getNodeId());
            nodeList.add(nodeMap);
        }

        return nodeList;

    }

    /**
     * 根据 nodeId 查询该节点的 JVM 监控信息。
     *
     * @param nodeId 节点唯一标识
     * @return MqttMetricCache 实例，包含节点的 JVM 信息
     * @throws ServiceException 如果 nodeId 为空或查询失败
     */
    public MqttMetricCache nodeJvmInfoNode(String nodeId) {
        if (Func.isEmpty(nodeId)) {
            throw new ServiceException(ResultCode.PARAM_MISS.getMessage());
        }


        ConditionGroup condition = new ConditionGroup()
                .add(ConditionQ.eq(MqttMetricCache::getNodeId, nodeId));
        return this.selectOne(condition, MqttMetricCache.class);

    }

    /**
     * 根据 nodeId 查询节点的详细指标信息，并解析为 Map 形式返回。
     *
     * @param nodeId 节点唯一标识
     * @return 包含指标数据的 Map，如果无数据则返回空 Map
     * @throws ServiceException 如果 nodeId 为空或解析失败
     */
    public Map<String, Object> metricNodeInfo(String nodeId) {
        if (Func.isEmpty(nodeId)) {
            throw new ServiceException(ResultCode.PARAM_MISS.getMessage());
        }


        ConditionGroup condition = new ConditionGroup()
                .add(ConditionQ.eq(MqttMetricCache::getNodeId, nodeId));
        MqttMetricCache metricCache = this.selectOne(condition, MqttMetricCache.class);

        Map<String, Object> result = new HashMap<>();

        if (metricCache != null && Func.isNotEmpty(metricCache.getMetric())) {
            result = JSON.parseObject(metricCache.getMetric(), Map.class);
        }

        return result;

    }

    /**
     * 查询指定节点的端点信息。
     *
     * @param nodeId 节点唯一标识
     * @return MqttMetricCache 实例，包含节点的端点信息
     * @throws ServiceException 如果 nodeId 为空或查询失败
     */
    public MqttMetricCache endpointNodes(String nodeId) {
        if (Func.isEmpty(nodeId)) {
            throw new ServiceException(ResultCode.PARAM_MISS.getMessage());
        }

        ConditionGroup condition = new ConditionGroup()
                .add(ConditionQ.eq(MqttMetricCache::getNodeId, nodeId));
        return this.selectOne(condition, MqttMetricCache.class);

    }
}